﻿
using System;
using System.Drawing;

using System.Collections;

namespace GECS.GraphicsUtil {

	/// <summary>
	/// Contains the list of images and frame timing information to create an animation.
	/// </summary>
    public class Animation {

        // Collection of frames in the animation
        private ArrayList images = null;
        private ArrayList durations = null;

        // The index of current frame
        private int currFrameIndex = 0;
        // The duration spent in the current frame
        private long duration = 0;

        // The paused property
        private bool paused = false;

        /// <summary>
        /// The default constructor could be used to create an empty Animation object.
        /// Then use the addFrame() method to add sub images with specific delay.
        /// </summary>
        public Animation() {
            images = new ArrayList();
            durations = new ArrayList();
        }

        /// <summary>
        /// This constructor is useful when you have same duration for every frame
        /// and could add frames from an image array.
        /// </summary>
        /// <param name="frames">The image array containing all the frames.</param>
        /// <param name="duration">The common duration of each and every image.</param>
        public Animation(Image[] frames, int duration) {        	
            images = new ArrayList();
            durations = new ArrayList();
            for (int i = 0; i < frames.Length; i++) {
            	AddFrame(frames[i], duration);
            }
        }
        
        /// <summary>
        /// Adds an image as a frame in this animation with a delay.
        /// </summary>
        /// <param name="frame">The frame image.</param>
        /// <param name="duration">Duration of the frame (in ms)</param>
        public void AddFrame(Image frame, int duration) {
            images.Add(frame);
            durations.Add((long)duration);
        }

        /// <summary>
        /// Updates the current animation object.
        /// </summary>
        /// <param name="elapsedTime">The time spent in current frame.</param>
        public void Update(long elapsedTime) {
            if (!paused) {
                duration += elapsedTime;
            }
        	if (duration >= (long)durations[currFrameIndex]) {
                duration = 0;
                NextFrame();
            }
        }

        /// <summary>
        /// Skip this frame and move to the next one. Note
        /// that all the frames are looped constantly.
        /// </summary>
        public void NextFrame() {
            currFrameIndex++;
            if (currFrameIndex >= images.Count) {
                currFrameIndex = 0;
            }
        }

        /// <summary>
        /// Displays the previous frame. Note that all
        /// the frames are looped constantly.
        /// </summary>
        public void PreviousFrame() {
            currFrameIndex--;
            if (currFrameIndex < 0) {
                currFrameIndex = 0;
            }
        }

        /// <summary>
        /// Gets you the current frame image of this animation object.
        /// </summary>
        /// <returns>The current frame as an image.</returns>
        public Image GetImage() {
        	return (Image)images[currFrameIndex];
        }

        /// <summary>
        /// Pause this animation.
        /// </summary>
        public void Pause() {
            paused = true;
        }

        /// <summary>
        /// Resume this animation.
        /// </summary>
        public void Resume() {
            paused = false;
        }

        /// <summary>
        /// Returns whether the animation is paused or not.
        /// </summary>
        /// <returns>The paused state.</returns>
        public bool IsPaused() {
            return paused;
        }

        /// <summary>
        /// Clones this animation with all the data.
        /// </summary>
        /// <returns>A clone of this animation.</returns>
        public Animation Clone() {
            Animation clone = new Animation();
            for (int i = 0; i < images.Count; i++) {
            	clone.AddFrame((Image)images[i], (int)durations[i]);
            }
            return clone;
        }

    }

}
